#include "StdAfx.h"
#include "FrogPdfAlbumDialog.h"

#pragma warning(disable:4482)

CFrogPdfAlbumDialog::CFrogPdfAlbumDialog(list<wstring> filesList, HICON hIcon):
CFrogProgressReportDialog(hIcon),
m_LastRows(-1),
m_LastCols(-1),
m_LastIsLandscape(false),
m_LastPicBorders(false),
m_LastMargins(-1),
m_LastGapPics(-1),
m_TempBmp(NULL),
m_Image(NULL),
m_OrderBy(0),
m_FilerFrogFilesListSorter(filesList)
{
	m_PdfAlbumCommandArgs.FilesList = filesList;
	m_PdfAlbumCommandArgs.Rows = 2;
	m_PdfAlbumCommandArgs.Cols = 2;
	m_PdfAlbumCommandArgs.PageSize = HPDF_PAGESIZES::PAGE_SIZE_A4;
	m_PdfAlbumCommandArgs.Optimize = true;
	m_PdfAlbumCommandArgs.Margins = 28;
	m_PdfAlbumCommandArgs.GapPics = 56;

	InitImageList();
}

void CFrogPdfAlbumDialog::InitImageList()
{
	if (m_Image)
	{
		delete m_Image;
		m_Image = NULL;
	}

	for (list<Gdiplus::Image*>::iterator iter = m_ImageList.begin(); iter != m_ImageList.end(); iter++)
	{
		Gdiplus::Image* image = *iter;
		delete image;
	}

	m_ImageList.clear();

	m_Image = new CGdiPlusBitmapResource();
	m_Image->Load(IDB_PNG_IMAGE, _T("PNG"), _AtlBaseModule.GetResourceInstance());

	int i = 0;

	for (list<wstring>::iterator iter = m_PdfAlbumCommandArgs.FilesList.begin(); iter != m_PdfAlbumCommandArgs.FilesList.end(); iter++)
	{
		wstring fileName = *iter;				
		Gdiplus::Image* image = Gdiplus::Image::FromFile(fileName.c_str());

		if (image != NULL)
		{
			m_ImageList.push_back(image);
		}

		i++;

		if (i == 16)
		{
			break;
		}
	}
}

CFrogPdfAlbumDialog::~CFrogPdfAlbumDialog()
{
	if (m_Image)
	{
		delete m_Image;
		m_Image = NULL;
	}

	for (list<Gdiplus::Image*>::iterator iter = m_ImageList.begin(); iter != m_ImageList.end(); iter++)
	{
		Gdiplus::Image* image = *iter;
		delete image;
	}

	m_ImageList.clear();

	m_PdfAlbumCommandArgs.FilesList.clear();

	if (m_TempBmp)
	{
		delete m_TempBmp;
		m_TempBmp = NULL;
	}
}

LRESULT CFrogPdfAlbumDialog::OnInitDialog(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
{
	CFrogProgressReportDialog::OnInitDialog(uMsg, wParam, lParam, bHandled);

	HWND spinHwndR = GetDlgItem(IDC_SPIN_R);
	SendMessage(spinHwndR, (UINT) UDM_SETRANGE, (WPARAM)0, (LPARAM)MAKELONG((short)32, (short)1));

	HWND spinHwndC = GetDlgItem(IDC_SPIN_C);
	SendMessage(spinHwndC, (UINT) UDM_SETRANGE, (WPARAM)0, (LPARAM)MAKELONG((short)32, (short)1));

	HWND spinHwndGap = GetDlgItem(IDC_SPIN_GAP);
	SendMessage(spinHwndGap, (UINT) UDM_SETRANGE, (WPARAM)0, (LPARAM)MAKELONG((short)999, (short)0));

	HWND spinHwndMargin = GetDlgItem(IDC_SPIN_MARGIN);
	SendMessage(spinHwndMargin, (UINT) UDM_SETRANGE, (WPARAM)0, (LPARAM)MAKELONG((short)999, (short)0));

	HWND pagesHwnd = GetDlgItem(IDC_COMBO_PAGE_SIZE);
	SendMessage(pagesHwnd,(UINT)CB_ADDSTRING, 0, (LPARAM)L"LETTER");
	SendMessage(pagesHwnd,(UINT)CB_ADDSTRING, 0, (LPARAM)L"LEGAL");
	SendMessage(pagesHwnd,(UINT)CB_ADDSTRING, 0, (LPARAM)L"A3");
	SendMessage(pagesHwnd,(UINT)CB_ADDSTRING, 0, (LPARAM)L"A4");
	SendMessage(pagesHwnd,(UINT)CB_ADDSTRING, 0, (LPARAM)L"A5");
	SendMessage(pagesHwnd,(UINT)CB_ADDSTRING, 0, (LPARAM)L"B4");
	SendMessage(pagesHwnd,(UINT)CB_ADDSTRING, 0, (LPARAM)L"B5");
	SendMessage(pagesHwnd,(UINT)CB_ADDSTRING, 0, (LPARAM)L"EXECUTIVE");
	SendMessage(pagesHwnd,(UINT)CB_ADDSTRING, 0, (LPARAM)L"US4x6");
	SendMessage(pagesHwnd,(UINT)CB_ADDSTRING, 0, (LPARAM)L"US4x8");
	SendMessage(pagesHwnd,(UINT)CB_ADDSTRING, 0, (LPARAM)L"US5x7");
	SendMessage(pagesHwnd,(UINT)CB_ADDSTRING, 0, (LPARAM)L"COMM10");
	SendMessage(pagesHwnd,(UINT)CB_ADDSTRING, 0, (LPARAM)L"US8x10");
	SendMessage(pagesHwnd,(UINT)CB_ADDSTRING, 0, (LPARAM)L"US9x12");
	SendMessage(pagesHwnd,(UINT)CB_ADDSTRING, 0, (LPARAM)L"US3_5x5");
	SendMessage(pagesHwnd,(UINT)CB_ADDSTRING, 0, (LPARAM)L"WALLET");
	SendMessage(pagesHwnd,(UINT)CB_ADDSTRING, 0, (LPARAM)L"320x464cm");	

	SendMessage(pagesHwnd,(UINT)CB_SETCURSEL, (WPARAM)m_PdfAlbumCommandArgs.PageSize , 0);

	HWND editRow = GetDlgItem(IDC_EDIT_ROWS);
	HWND editCol = GetDlgItem(IDC_EDIT_COLS);

	::SetWindowText(editRow, L"2");
	::SetWindowText(editCol, L"2");

	HWND editGap = GetDlgItem(IDC_EDIT_GAP);
	HWND editMargin = GetDlgItem(IDC_EDIT_MARGIN);

	::SetWindowText(editGap, L"56");
	::SetWindowText(editMargin, L"28");

	HWND buttonIsLandScape = GetDlgItem(IDC_CHECK_LANDSCAPE);
	LRESULT lResult = SendMessage(buttonIsLandScape, (UINT)BM_GETCHECK, 0, 0);

	if (lResult != BST_CHECKED)
	{
		m_PdfAlbumCommandArgs.IsLandscape = false;
	}
	else
	{
		m_PdfAlbumCommandArgs.IsLandscape = true;
	}

	HWND buttonIsBroders = GetDlgItem(IDC_CHECK_BORDERS);
	lResult = SendMessage(buttonIsBroders, (UINT)BM_GETCHECK, 0, 0);

	if (lResult != BST_CHECKED)
	{
		m_PdfAlbumCommandArgs.PicBorders = false;
	}
	else
	{
		m_PdfAlbumCommandArgs.PicBorders = true;
	}

	HWND buttonIsOptimize = GetDlgItem(IDC_CHECK_OPTIMIZE);
	lResult = SendMessage(buttonIsOptimize, (UINT)BM_GETCHECK, 0, 0);

	if (lResult != BST_CHECKED)
	{
		m_PdfAlbumCommandArgs.Optimize = false;
	}
	else
	{
		m_PdfAlbumCommandArgs.Optimize = true;
	}

	::SetFocus(m_hWnd);

	DoDataExchange(FALSE);

	return 0;
}


void CFrogPdfAlbumDialog::DrawPreviewControl(bool repaint)
{
	HWND previewCtrl = GetDlgItem(IDC_PREVIEW);
	RECT windowRect;
	::GetWindowRect(previewCtrl, &windowRect);

	int w = windowRect.right - windowRect.left;
	int h = windowRect.bottom - windowRect.top;

	bool wasChanged = false;

	if (m_TempBmp == NULL)
	{
		m_TempBmp = new Bitmap(w, h);
		wasChanged = true;
	}
	else
	{
		wasChanged = (
			m_LastRows != m_PdfAlbumCommandArgs.Rows ||
			m_LastCols != m_PdfAlbumCommandArgs.Cols ||
			m_LastIsLandscape != m_PdfAlbumCommandArgs.IsLandscape ||
			m_LastPicBorders != m_PdfAlbumCommandArgs.PicBorders ||
			m_LastMargins != m_PdfAlbumCommandArgs.Margins ||
			m_LastGapPics != m_PdfAlbumCommandArgs.GapPics);
	}

	Graphics backBuffer(m_TempBmp);
	Graphics graphics(previewCtrl);	

	if (wasChanged || repaint)
	{
		m_LastRows = m_PdfAlbumCommandArgs.Rows;
		m_LastCols = m_PdfAlbumCommandArgs.Cols;
		m_LastIsLandscape = m_PdfAlbumCommandArgs.IsLandscape;
		m_LastPicBorders = m_PdfAlbumCommandArgs.PicBorders;
		m_LastMargins = m_PdfAlbumCommandArgs.Margins;
		m_LastGapPics = m_PdfAlbumCommandArgs.GapPics;

		backBuffer.Clear(Color::Gray);

		SolidBrush whiteBrush(Color::White);

		int x = 0;
		int y = 0;

		Rect paperRect(x + 10, y + 10, w - 20, h - 20);

		if (m_PdfAlbumCommandArgs.IsLandscape)
		{
			paperRect.X = x + 10;
			paperRect.Y = y + ( h / 2) + 10;

			paperRect.Width = w - 20;
			paperRect.Height = (h / 2) - 20;

			paperRect.Y = paperRect.Y - (paperRect.Height / 2);
		}

		backBuffer.FillRectangle(&whiteBrush, paperRect);

		int pageMargin = (int)(4 * m_PdfAlbumCommandArgs.Margins / 28);

		int ww = ((paperRect.Width - 2 * pageMargin) / m_PdfAlbumCommandArgs.Cols);
		int hh = ((paperRect.Height - 2 * pageMargin) / m_PdfAlbumCommandArgs.Rows);

		for (int x=0; x < m_PdfAlbumCommandArgs.Cols ; x++)
		{
			for (int y=0; y < m_PdfAlbumCommandArgs.Rows ; y++)
			{
				int PosY = paperRect.Y + pageMargin;
				int PosX = paperRect.X + pageMargin;

				int marginX = (int)(4 * m_PdfAlbumCommandArgs.GapPics / 56);
				int marginY = (int)(4 * m_PdfAlbumCommandArgs.GapPics / 56);			

				int locX = marginX + PosX + x * ww;
				int locY = marginY + PosY + y * hh;

				int idx = x + (y * m_PdfAlbumCommandArgs.Cols);
				Gdiplus::Image* image = GetImageAtIndex(idx);

				if (image)
				{
					backBuffer.DrawImage(image, locX, locY, ww - 2 * marginX, hh - 2 * marginY);
				}

				if (m_PdfAlbumCommandArgs.PicBorders)
				{
					Gdiplus::Pen blackPen(Color(255, 0, 0, 0), 1.0);
					backBuffer.DrawRectangle(&blackPen, locX - (marginX/2) , locY - (marginY/2), ww - marginX, hh - marginY);
				}
			}
		}
	}
	graphics.DrawImage(m_TempBmp, 0, 0);
}

Gdiplus::Image* CFrogPdfAlbumDialog::GetImageAtIndex(int idx)
{
	int i = 0;

	for (list<Gdiplus::Image*>::iterator iter = m_ImageList.begin(); iter != m_ImageList.end(); iter++)
	{
		Gdiplus::Image* image = *iter;

		if (i== idx)
		{
			return image;
		}
		i++;
	}

	if (m_Image)
	{
		return (Gdiplus::Image*)m_Image->m_pBitmap;
	}
	else
	{
		return NULL;
	}
}
LRESULT CFrogPdfAlbumDialog::OnPaint(UINT /*uMsg*/, WPARAM /*wParam*/, LPARAM /*lParam*/, BOOL& bHandled)
{
	// TODO: Add your message handler code here and/or call default
	bHandled = FALSE;
	DrawPreviewControl();	
	return 0;
}

LRESULT CFrogPdfAlbumDialog::OnEnChangeEditRows(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& bHandled)
{
	bHandled = TRUE;

	wchar_t buffer[256];

	GetDlgItemText(IDC_EDIT_ROWS, buffer, 256);

	int rows = _wtoi(buffer);

	if (rows > 0)
	{
		if (rows > 64)
		{
			m_PdfAlbumCommandArgs.Rows = 100;
		}
		else
		{
			m_PdfAlbumCommandArgs.Rows = rows;
		}

		DrawPreviewControl();
	}

	return 0;
}

LRESULT CFrogPdfAlbumDialog::OnEnChangeEditCols(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& bHandled)
{
	bHandled = TRUE;

	wchar_t buffer[256];

	GetDlgItemText(IDC_EDIT_COLS, buffer, 256);

	int cols = _wtoi(buffer);

	if (cols > 0)
	{
		if (cols > 64)
		{
			m_PdfAlbumCommandArgs.Cols = 100;
		}
		else
		{
			m_PdfAlbumCommandArgs.Cols = cols;
		}

		DrawPreviewControl();
	}

	return 0;
}

LRESULT CFrogPdfAlbumDialog::OnEnChangeEditGap(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& bHandled)
{
	bHandled = TRUE;

	wchar_t buffer[256];
	GetDlgItemText(IDC_EDIT_GAP, buffer, 256);
	m_PdfAlbumCommandArgs.GapPics = (HPDF_REAL)_wtoi(buffer);
	DrawPreviewControl();

	return 0;
}

LRESULT CFrogPdfAlbumDialog::OnEnChangeEditMargin(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& bHandled)
{
	bHandled = TRUE;

	wchar_t buffer[256];
	GetDlgItemText(IDC_EDIT_MARGIN, buffer, 256);
	m_PdfAlbumCommandArgs.Margins = (HPDF_REAL)_wtoi(buffer);
	DrawPreviewControl();

	return 0;
}

LRESULT CFrogPdfAlbumDialog::OnBnClickedOk(WORD /*wNotifyCode*/, WORD wID, HWND /*hWndCtl*/, BOOL& bHandled)
{	
	bHandled = TRUE;

	DoDataExchange(TRUE);

	// TODO: Add your control notification handler code here
	wchar_t buffer[256];
	GetDlgItemText(IDC_EDIT_COLS, buffer, 256);
	m_PdfAlbumCommandArgs.Cols = _wtoi(buffer);

	GetDlgItemText(IDC_EDIT_ROWS, buffer, 256);
	m_PdfAlbumCommandArgs.Rows = _wtoi(buffer);

	GetDlgItemText(IDC_EDIT_GAP, buffer, 256);
	m_PdfAlbumCommandArgs.GapPics = (HPDF_REAL)_wtoi(buffer);

	GetDlgItemText(IDC_EDIT_MARGIN, buffer, 256);
	m_PdfAlbumCommandArgs.Margins = (HPDF_REAL)_wtoi(buffer);

	HWND pageSizeHwnd = GetDlgItem(IDC_COMBO_PAGE_SIZE);
	LRESULT lResult = SendMessage(pageSizeHwnd,(UINT)CB_GETCURSEL, 0 , 0);

	if (lResult == CB_ERR)
	{
		m_PdfAlbumCommandArgs.PageSize = HPDF_PAGESIZES::PAGE_SIZE_A4;
	}
	else
	{
		m_PdfAlbumCommandArgs.PageSize = (HPDF_PAGESIZES)lResult;
	}

	HWND buttonIsLandScape = GetDlgItem(IDC_CHECK_LANDSCAPE);
	lResult = SendMessage(buttonIsLandScape, (UINT)BM_GETCHECK, 0, 0);

	if (lResult != BST_CHECKED)
	{
		m_PdfAlbumCommandArgs.IsLandscape = false;
	}
	else
	{
		m_PdfAlbumCommandArgs.IsLandscape = true;
	}

	HWND buttonIsBroders = GetDlgItem(IDC_CHECK_BORDERS);
	lResult = SendMessage(buttonIsBroders, (UINT)BM_GETCHECK, 0, 0);

	if (lResult != BST_CHECKED)
	{
		m_PdfAlbumCommandArgs.PicBorders = false;
	}
	else
	{
		m_PdfAlbumCommandArgs.PicBorders = true;
	}

	HWND buttonIsOptimize = GetDlgItem(IDC_CHECK_OPTIMIZE);
	lResult = SendMessage(buttonIsOptimize, (UINT)BM_GETCHECK, 0, 0);

	if (lResult != BST_CHECKED)
	{
		m_PdfAlbumCommandArgs.Optimize = false;
	}
	else
	{
		m_PdfAlbumCommandArgs.Optimize = true;
	}

	SortFilesList();

	RunAsyncCommandWithProgressBar();

	EndDialog(wID);
	return 0;
}

void CFrogPdfAlbumDialog::ExecuteCommand()
{
	wstring pdfPath = m_FolderPath + L"\\PhotoAlbum.pdf";
	PDFFile pdfFile(pdfPath.c_str());

	int rows = m_PdfAlbumCommandArgs.Rows;
	int cols = m_PdfAlbumCommandArgs.Cols;
	bool isLandscape = m_PdfAlbumCommandArgs.IsLandscape;
	HPDF_PAGESIZES pageSize =  m_PdfAlbumCommandArgs.PageSize;
	bool picBorders = m_PdfAlbumCommandArgs.PicBorders;
	bool optimize = m_PdfAlbumCommandArgs.Optimize;
	HPDF_REAL margins = m_PdfAlbumCommandArgs.Margins;
	HPDF_REAL gapPics = m_PdfAlbumCommandArgs.GapPics;

	PDFTemplates::T_DynamicTemplate(pdfFile, rows, cols, isLandscape, pageSize, picBorders, m_PdfAlbumCommandArgs.FilesList, optimize, margins, gapPics);

	m_FilesRefactor.GeneratePdf(m_LastResult, pdfFile);
}

LRESULT CFrogPdfAlbumDialog::OnBnClickedCheckLandscape(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& bHandled)
{
	bHandled = TRUE;

	HWND button = GetDlgItem(IDC_CHECK_LANDSCAPE);

	LRESULT lResult = SendMessage(button, (UINT)BM_GETCHECK, 0, 0);

	if (lResult == BST_CHECKED)
	{
		m_PdfAlbumCommandArgs.IsLandscape = true;
	}
	else
	{
		m_PdfAlbumCommandArgs.IsLandscape = false;
	}

	DrawPreviewControl();

	return 0;
}

LRESULT CFrogPdfAlbumDialog::OnBnClickedCheckBorders(WORD /*wNotifyCode*/, WORD /*wID*/, HWND /*hWndCtl*/, BOOL& bHandled)
{
	bHandled = TRUE;

	HWND button = GetDlgItem(IDC_CHECK_BORDERS);

	LRESULT lResult = SendMessage(button, (UINT)BM_GETCHECK, 0, 0);

	if (lResult == BST_CHECKED)
	{
		m_PdfAlbumCommandArgs.PicBorders = true;
	}
	else
	{
		m_PdfAlbumCommandArgs.PicBorders = false;
	}

	DrawPreviewControl();

	return 0;
}

LRESULT CFrogPdfAlbumDialog::OnRadioOrderBnClicked(WORD wNotifyCode, WORD wID, HWND hWndCtl, BOOL& bHandled)
{
	bHandled = TRUE;
	DoDataExchange(TRUE);
	SortFilesList();
	DrawPreviewControl(true);
	return 0;
}

void CFrogPdfAlbumDialog::SortFilesList()
{
	switch (m_OrderBy)
	{
	case 0:
		{
			m_PdfAlbumCommandArgs.FilesList.clear();
			m_FilerFrogFilesListSorter.SortListRandom(m_PdfAlbumCommandArgs.FilesList);
		}
		break;
	case 1:
		{
			m_PdfAlbumCommandArgs.FilesList.clear();
			m_FilerFrogFilesListSorter.SortListByName(m_PdfAlbumCommandArgs.FilesList);
		}
		break;
	case 2:
		{
			m_PdfAlbumCommandArgs.FilesList.clear();
			m_FilerFrogFilesListSorter.SortListFileDate(m_PdfAlbumCommandArgs.FilesList);
		}
		break;
	}

	InitImageList();
}